/**
 * 
 */
package co.fitstart.mobile.web.controller.trading;

import java.util.List;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.demo2do.core.BusinessException;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.wechat.web.interceptor.WechatJsConfig;
import co.fitstart.entity.coupon.Coupon;
import co.fitstart.entity.order.Order;
import co.fitstart.entity.product.Product;
import co.fitstart.entity.product.Status;
import co.fitstart.entity.user.User;
import co.fitstart.mobile.cache.accessor.PersistentAccessor;
import co.fitstart.mobile.entity.UserContext;
import co.fitstart.mobile.entity.trading.Shopping;
import co.fitstart.mobile.handler.QrcodeHandler;
import co.fitstart.mobile.service.CouponService;
import co.fitstart.mobile.service.DistributorService;
import co.fitstart.mobile.service.OrderService;
import co.fitstart.mobile.service.ProductService;
import co.fitstart.mobile.web.interceptor.MobileDetect;
import co.fitstart.mobile.web.interceptor.Router;
import co.fitstart.mobile.web.resolver.Secure;

/**
 * Trading process related controller, including all the page level navigation
 * 
 * @author downpour
 */
@Controller
@RequestMapping("")
public class TradingProcessController {
    
    private static final Logger logger = LoggerFactory.getLogger(TradingProcessController.class);

    @Autowired
    private ProductService productService;
    
    @Autowired
    private CouponService couponService;
    
    @Autowired
    private OrderService orderService;
    
    @Autowired
    private DistributorService distributorService;
    
    @Autowired
    private PersistentAccessor persistentAccessor;
    
    @Autowired
    private QrcodeHandler qrcodeHandler;
    
    /**
     * Prepare to go to shopping page
     * 
     * @param user
     * @param productId
     * @param source
     * @return
     */
    @RequestMapping(value = "/shop2", method = RequestMethod.GET)
    @Router
    @MobileDetect
    @WechatJsConfig
    public ModelAndView shop2(@Secure User user,
                             @RequestParam("sku") Long productId, 
                             @RequestParam("source") String source,
                             @RequestParam(name = "distributorId", required = false) Long distributorId) {
        
        ModelAndView modelAndView = new ModelAndView("trading/shopping2");
        
        // 1. prepare sku for display
        Product product = productService.load(Product.class, productId);
        modelAndView.addObject("product", product);

        if(product == null || product.getStatus() != Status.ONLINE || product.isDisabled() || !product.isBuyable()) {
            modelAndView.setViewName("product/product-error");
            return modelAndView;
        }
        
        // 2. get sites data from persist when product is offline product
        if(product.getType().isOffline()) {
            modelAndView.addObject("siteSelect", JsonUtils.toJsonString(persistentAccessor.sites(product)));
        }
        
        // 4. bind userCoupon & count avaliable coupon here
        if(user != null) {
            
            if(distributorId != null) {
                distributorService.createRelation(distributorId, user);
            }
            
            int couponAmount = couponService.syncCoupon(user, product);
            modelAndView.addObject("couponAmount", couponAmount);
            
            modelAndView.addObject("user", user);
            
        }
        
        return modelAndView;
    
    }
    /**
     * Prepare to go to shopping page
     * 
     * @param user
     * @param productId
     * @param source
     * @return
     */
    @RequestMapping(value = "/shop", method = RequestMethod.GET)
    @Router
    @MobileDetect
    @WechatJsConfig
    public ModelAndView shop(@Secure User user,
                             @RequestParam("sku") Long productId, 
                             @RequestParam("source") String source,
                             @RequestParam(name = "distributorId", required = false) Long distributorId) {
        
        ModelAndView modelAndView = new ModelAndView("trading/shopping");
        
        // 1. prepare sku for display
        Product product = productService.load(Product.class, productId);
        modelAndView.addObject("product", product);

        if(product == null || product.getStatus() != Status.ONLINE || product.isDisabled() || !product.isBuyable()) {
            modelAndView.setViewName("product/product-error");
            return modelAndView;
        }
        
        // 2. get sites data from persist when product is offline product
        if(product.getType().isOffline()) {
            modelAndView.addObject("siteSelect", JsonUtils.toJsonString(persistentAccessor.sites(product)));
        }
        
        // 4. bind userCoupon & count avaliable coupon here
        if(user != null) {
            
            if(distributorId != null) {
                distributorService.createRelation(distributorId, user);
            }
            
            int couponAmount = couponService.syncCoupon(user, product);
            modelAndView.addObject("couponAmount", couponAmount);
            
            modelAndView.addObject("user", user);
            
        }
        
        return modelAndView;
    
    }
    /**
     * Prepare to go to shopping page
     * 
     * @param user
     * @param productId
     * @param source
     * @return
     */
    @RequestMapping(value = "/shop3", method = RequestMethod.GET)
    @Router
    @MobileDetect
    @WechatJsConfig
    public ModelAndView shop3(@Secure User user,
                             @RequestParam("sku") Long productId, 
                             @RequestParam("source") String source,
                             @RequestParam(name = "distributorId", required = false) Long distributorId) {
        
        ModelAndView modelAndView = new ModelAndView("trading/shopping3");
        
        // 1. prepare sku for display
        Product product = productService.load(Product.class, productId);
        modelAndView.addObject("product", product);

        if(product == null || product.getStatus() != Status.ONLINE || product.isDisabled() || !product.isBuyable()) {
            modelAndView.setViewName("product/product-error");
            return modelAndView;
        }
        
        // 2. get sites data from persist when product is offline product
        if(product.getType().isOffline()) {
            modelAndView.addObject("siteSelect", JsonUtils.toJsonString(persistentAccessor.sites(product)));
        }
        
        // 4. bind userCoupon & count avaliable coupon here
        if(user != null) {
            
            if(distributorId != null) {
                distributorService.createRelation(distributorId, user);
            }
            
            int couponAmount = couponService.syncCoupon(user, product);
            modelAndView.addObject("couponAmount", couponAmount);
            
            modelAndView.addObject("user", user);
            
        }
        
        return modelAndView;
    
    }
    
    /**
     * Display shop landing page when user's from non-WeChat browser
     * 
     * @return
     */
    @RequestMapping("/shop-landing")
    public String shopLanding() {
        return "trading/shopping-landing";
    }
    
    /**
     * @param user
     * @param shopping
     * @return
     */
    @RequestMapping(value = "/orders", method = RequestMethod.POST)
    public @ResponseBody String onSumitOrder(@Secure User user,
                                             Shopping shopping) {
        
        Result result = new Result();
        
        try {
            
            Long userId = user.getId();
            Order order = orderService.create(shopping.user(userId));
            
            if(shopping.getContact() != null && !StringUtils.isEmpty(shopping.getWechatNumber())) {
                qrcodeHandler.changeUserQrcode(user, shopping.getWechatNumber());
            }
            
            result.success()
                  .data("orderId", order.getId())
                  .message("创建订单成功");
            
        } catch (BusinessException e) {
            
            result.fail().message(e.getMessage());
            
        } catch (Exception e) {
            
            logger.error("#onSumitOrder() error ", e);
            
            result.fail()
                  .message("创建订单失败");
            
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * Prepare to pay order
     * 
     * @param user
     * @param userContext
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/pay", method = RequestMethod.POST)
    @Router
    @MobileDetect
    @WechatJsConfig
    public ModelAndView payment(@Secure User user,
                                UserContext userContext,
                                @RequestParam("order") Long orderId) {
        // 1. prepare order data
        Order order = orderService.load(Order.class, orderId);
        
        ModelAndView modelAndView;
        if(order.getOrderType().isOnline() && !order.isOnlineYear() && order.getPrice() == 0 ) {
            modelAndView = new ModelAndView("trading/online-order-confirm");
        } else if(userContext.isMicroMessenger()) {
            modelAndView = new ModelAndView("trading/wechat-payment");
        } else {
            modelAndView = new ModelAndView("trading/ali-payment");
        }

        // 2. check whether userId matches order's user id
        if(!order.matches(user.getId())) {
            
            // goes to error page when not match
            modelAndView.setViewName("order-error");
            return modelAndView;
        }
        
        // 3. add order to model for display
        modelAndView.addObject("order", order);
        
        // 4. add coupon to model for display
        if(MapUtils.isNotEmpty(order.getAttrs()) && order.getAttrs().get("couponId") != null) {
            Long couponId = Long.parseLong(order.getAttrs().get("couponId").getValue());
            Coupon coupon = couponService.load(Coupon.class, couponId);
            modelAndView.addObject("coupon", coupon);
        }
        
        if(order.getOrderType().isOnline()) {
        	
        	String online = "ONLINE";
        	
        	modelAndView.addObject("orderType",online);
        }
        
        return modelAndView;
    
    }
    
    /**
     * Prepare to pay order
     * 
     * @param user
     * @param userContext
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/pay2", method = RequestMethod.POST)
    @Router
    @MobileDetect
    @WechatJsConfig
    public ModelAndView payment2(@Secure User user,
                                UserContext userContext,
                                @RequestParam("order") Long orderId) {
        // 1. prepare order data
        Order order = orderService.load(Order.class, orderId);
        
        ModelAndView modelAndView;
        if(order.getOrderType().isOnline() && !order.isOnlineYear() && order.getPrice() == 0 ) {
            modelAndView = new ModelAndView("trading/online-order-confirm2");
        } else if(userContext.isMicroMessenger()) {
            modelAndView = new ModelAndView("trading/wechat-payment2");
        } else {
            modelAndView = new ModelAndView("trading/ali-payment");
        }

        // 2. check whether userId matches order's user id
        if(!order.matches(user.getId())) {
            
            // goes to error page when not match
            modelAndView.setViewName("order-error");
            return modelAndView;
        }
        
        // 3. add order to model for display
        modelAndView.addObject("order", order);
        
        // 4. add coupon to model for display
        if(MapUtils.isNotEmpty(order.getAttrs()) && order.getAttrs().get("couponId") != null) {
            Long couponId = Long.parseLong(order.getAttrs().get("couponId").getValue());
            Coupon coupon = couponService.load(Coupon.class, couponId);
            modelAndView.addObject("coupon", coupon);
        }
        
        if(order.getOrderType().isOnline()) {
        	
        	String online = "ONLINE";
        	
        	modelAndView.addObject("orderType",online);
        }
        
        return modelAndView;
    
    }
    /**
     * Prepare to pay order
     * 
     * @param user
     * @param userContext
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/pay3", method = RequestMethod.POST)
    @Router
    @MobileDetect
    @WechatJsConfig
    public ModelAndView payment3(@Secure User user,
                                UserContext userContext,
                                @RequestParam("order") Long orderId) {
        // 1. prepare order data
        Order order = orderService.load(Order.class, orderId);
        
        ModelAndView modelAndView;
        if(order.getOrderType().isOnline() && !order.isOnlineYear() && order.getPrice() == 0 ) {
            modelAndView = new ModelAndView("trading/online-order-confirm2");
        } else if(userContext.isMicroMessenger()) {
            modelAndView = new ModelAndView("trading/wechat-payment3");
        } else { 
            modelAndView = new ModelAndView("trading/ali-payment");
        }

        // 2. check whether userId matches order's user id
        if(!order.matches(user.getId())) {
            
            // goes to error page when not match
            modelAndView.setViewName("order-error");
            return modelAndView;
        }
        
        // 3. add order to model for display
        modelAndView.addObject("order", order);
        
        // 4. add coupon to model for display
        if(MapUtils.isNotEmpty(order.getAttrs()) && order.getAttrs().get("couponId") != null) {
            Long couponId = Long.parseLong(order.getAttrs().get("couponId").getValue());
            Coupon coupon = couponService.load(Coupon.class, couponId);
            modelAndView.addObject("coupon", coupon);
        }
        
        if(order.getOrderType().isOnline()) {
        	
        	String online = "ONLINE";
        	
        	modelAndView.addObject("orderType",online);
        }
        
        return modelAndView;
    
    }
    
    
    @RequestMapping(value = "/orders/{orderId}/payment-protocol", method = RequestMethod.GET)
    @Router
    @MobileDetect
    @WechatJsConfig
    public ModelAndView protocol(@Secure User user,
            @PathVariable("orderId") Long orderId) {
    	
    	logger.info("LZJ get protocol orderId [{}]" , orderId);
    	
    	ModelAndView modelAndView = new ModelAndView("trading/payment-protocol");   	
    	
    	Order order = orderService.load(Order.class, orderId);
    	
    	modelAndView.addObject("order", order);
    	
    	return modelAndView;
    }

    /**
     * Order complete page
     * 
     * @param user
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/orders/{orderId}/complete", method = RequestMethod.GET)
    @Router
    @MobileDetect
    @WechatJsConfig
    public ModelAndView onCompletePayment(@Secure User user,
                                          @PathVariable("orderId") Long orderId) {
    	
    	logger.info("LZJ get complete orderId [{}]" , orderId);
        
        ModelAndView modelAndView = new ModelAndView();
        
        Long userId = user.getId();
        
        // 1. prepare order data
        Order order = orderService.load(Order.class, orderId);
        
        // 2. check whether userId matches order's user id
        if(!order.matches(userId)) {
            
            // goes to error page when not match
            modelAndView.setViewName("order-error");
            return modelAndView;
            
        }
        
        // 3. decide which view to display
        if(order.getOrderType().isOnline() && !order.isOnlineYear() && !order.isInvestiged()) {
            modelAndView.setViewName("redirect:/orders/" + order.getId() + "/investigations");
        } else if (order.getOrderType().isOffline() && !order.isInvestiged()) {
            modelAndView.setViewName("redirect:/orders/" + order.getId() + "/investigation-offlines");
        } else {
            if(order.getOrderType().isOnline() && order.isOnlineYear()) {
                List<Coupon> coupons = couponService.listCoupon(order);
                if(coupons != null && coupons.size() > 0) {
                    modelAndView.addObject("coupons", coupons);
                }
            }
            modelAndView.setViewName("trading/order-complete");
        }
        
        // 4. add order to model for display
        modelAndView.addObject("order", order);
        
        return modelAndView;
        
    }

    /**
     * Order complete page
     * 
     * @param user
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/orders/{orderId}/complete3", method = RequestMethod.GET)
    @Router
    @MobileDetect
    @WechatJsConfig
    public ModelAndView onCompletePayment3(@Secure User user,
                                          @PathVariable("orderId") Long orderId) {
    	
    	logger.info("LZJ get complete orderId [{}]" , orderId);
        
        ModelAndView modelAndView = new ModelAndView();
        
        Long userId = user.getId();
        
        // 1. prepare order data
        Order order = orderService.load(Order.class, orderId);
        
        // 2. check whether userId matches order's user id
        if(!order.matches(userId)) {
            
            // goes to error page when not match
            modelAndView.setViewName("order-error");
            return modelAndView;
            
        }
        
        // 3. decide which view to display
        if(order.getOrderType().isOnline() && !order.isOnlineYear() && !order.isInvestiged()) {
            // modelAndView.setViewName("redirect:/orders/" + order.getId() + "/investigations");
            modelAndView.setViewName("trading/order-complete3");

        } else if (order.getOrderType().isOffline() && !order.isInvestiged()) {
            modelAndView.setViewName("redirect:/orders/" + order.getId() + "/investigation-offlines");
        } else {
            if(order.getOrderType().isOnline() && order.isOnlineYear()) {
                List<Coupon> coupons = couponService.listCoupon(order);
                if(coupons != null && coupons.size() > 0) {
                    modelAndView.addObject("coupons", coupons);
                }
            }
            modelAndView.setViewName("trading/order-complete3");
        }
        
        // 4. add order to model for display
        modelAndView.addObject("order", order);
        
        return modelAndView;
        
    }
    /**
     * Order complete page
     * 
     * @param user
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/orders/{orderId}/complete2", method = RequestMethod.GET)
    @Router
    @MobileDetect
    @WechatJsConfig
    public ModelAndView onCompletePayment2(@Secure User user,
                                          @PathVariable("orderId") Long orderId) {
    	
    	logger.info("LZJ get complete orderId [{}]" , orderId);
        
        ModelAndView modelAndView = new ModelAndView();
        
        Long userId = user.getId();
        
        // 1. prepare order data
        Order order = orderService.load(Order.class, orderId);
        
        // 2. check whether userId matches order's user id
        if(!order.matches(userId)) {
            
            // goes to error page when not match
            modelAndView.setViewName("order-error");
            return modelAndView;
            
        }
        
        // 3. decide which view to display
        if(order.getOrderType().isOnline() && !order.isOnlineYear() && !order.isInvestiged()) {
            // modelAndView.setViewName("redirect:/orders/" + order.getId() + "/investigations");
            modelAndView.setViewName("trading/order-complete2");

        } else if (order.getOrderType().isOffline() && !order.isInvestiged()) {
            modelAndView.setViewName("redirect:/orders/" + order.getId() + "/investigation-offlines");
        } else {
            if(order.getOrderType().isOnline() && order.isOnlineYear()) {
                List<Coupon> coupons = couponService.listCoupon(order);
                if(coupons != null && coupons.size() > 0) {
                    modelAndView.addObject("coupons", coupons);
                }
            }
            modelAndView.setViewName("trading/order-complete2");
        }
        
        // 4. add order to model for display
        modelAndView.addObject("order", order);
        
        return modelAndView;
        
    }
}
